'''
Author: Donald duck tang5722917@163.com
Date: 2022-09-14 10:40:41
LastEditors: Donald duck tang5722917@163.com
LastEditTime: 2024-04-11 11:38:18
FilePath: \spice_netlist_front_end\src\Circuit\Circuit_element_fac.py
Description:

Copyright (c) 2022 by Donald duck tang5722917@163.com, All Rights Reserved.
'''
from Circuit_element import Element_R
from Circuit_element import Element_V
from Circuit_element import Element_I
from Circuit_control import Control_fac
from Net_syntax import Netlist_lex
from Net_syntax import Control_Line_lex
from transitions import Machine, State

class Circuit_element_fac :
    transitions = [
        {'trigger': 'enter_control', 'source': 'NET_LINE', 'dest': 'CONTROL_LINE'},
        {'trigger': 'exit_control', 'source': 'CONTROL_LINE', 'dest': 'NET_LINE'},
        {'trigger': 'exit_line', 'source': 'NET_LINE', 'dest': 'END_LINE'},
    ]
    
    def say_hello(self):
        pass

    def say_goodbye(self):
        pass
    
    def enter_netline_event(self):
        pass
    
    def enter_controlline_event(self):
        pass 
    
    def enter_endline_event(self):
        pass
    
    def __init__(self,Debug_enable,logging):
        self.type = {
            "VSource_net_element"   : self.get_VSource_net_element,
            "R_net_element"         : self.get_R_net_element,
            "CONTROL"               : self.get_Control_element,
            "Comment"               : self.get_Comment,
        }
        states = [
            State(name='NET_LINE', on_enter='enter_netline_event', on_exit='say_goodbye'),
            State(name='CONTROL_LINE', on_enter='enter_controlline_event', on_exit='say_goodbye'),
            State(name='END_LINE', on_enter='enter_endline_event', on_exit='say_goodbye'),
        ]
        self.machine = Machine(model=self, states=states, transitions=Circuit_element_fac.transitions, initial='NET_LINE')
        self.control_fac = Control_fac.Control_fac()
        self.Debug_enable = Debug_enable
        self.logging = logging
        self.trigger_type = {
            "endc"      : self.exit_control,
            "end"       : self.exit_line,
            "control"  : self.enter_control,
        }
        
     #V source obj
    def get_VSource_net_element(self,line_ob): 
        obj = Element_V.Element_V(line_ob.toks[0].value)
        obj.import_elem(line_ob)
        return [obj,0]
    #Resistor obj    
    def get_R_net_element(self,line_ob):
        obj = Element_R.Element_R(line_ob.toks[0].value)
        obj.import_elem(line_ob)
        return [obj,0]
    #Control obj    
    def get_Control_element(self,line_ob):
        return self.control_fac.import_elem(line_ob)
    
    def get_Comment(self,line_ob):
        return [-1,-1]
    
    def mach_state_switch(self,value):
        func = self.trigger_type.get(value)
        if func:
            func()
        else:
            pass
    
    def netlist_element_deal(self,net_line,lineno):
        if self.state == 'NET_LINE' :
            line_ob = Netlist_lex.get_net_line_ob(net_line,lineno,self.Debug_enable,self.logging)
            if(line_ob.toks[0].type == "CONTROL"):
                self.mach_state_switch(line_ob.toks[0].value[1])
            func = self.type.get(line_ob.toks[0].type)
    # result [obj,statue]
    # statue 0 : Element obj , 1 : Control obj , 2 : Model obj , 0 < error
            if func:
                return func(line_ob)
            else:return [-3,-3]
        elif self.state == 'CONTROL_LINE':
            control_line = Control_Line_lex.net_syntax(net_line,self.Debug_enable,self.logging)
            self.mach_state_switch(control_line[0])
            return [control_line,3]
        elif self.state == 'END_LINE':
            return [5,5]
        else: return[-3,-3]
